package com.microservice.base.service.impl;

import com.microservice.base.entity.Org;
import com.microservice.base.entity.SysTreeview;
import com.microservice.base.mapper.hikcommon.OrgMP;
import com.microservice.base.mapper.hikcommon.SysTreeviewMP;
import com.microservice.base.service.TbOrgSV;
import com.microservice.base.vo.searchVo.SearchVo;
import com.microservice.base.vo.searchVo.SysTreeviewSearchVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author jbx
 * @package_name com.microservice.base.service.impl
 * @create_date 2020/12/7 10:07
 */
@Service
public class TbOrgSVI implements TbOrgSV {
  @Autowired private OrgMP orgMP;
  @Autowired private SysTreeviewMP sysTreeviewMP;

  @Override
  public void save(Org org) {
    // 保存的逻辑简单,只需要调用mp进行保存即可
    orgMP.save(org);
  }

  @Override
  public void saveBatch(List<Org> list) {}

  @Override
  public void delete(String id) {}

  @Override
  public void deleteBatch(String[] ids) {}

  @Override
  public int update(Org org) {
    return 0;
  }

  @Override
  public List<Org> query(SearchVo searchVo) {
    return null;
  }

  @Override
  public Org get(String id) {
    return null;
  }

  @Override
  public int getCount(SearchVo searchVo) {
    return 0;
  }

  @Override
  public List<Org> queryAll() {
    List<Org> orgs = orgMP.queryAll();
    return orgs;
  }

  /**
   * 树关系转换为组织关系,操作类型的传值为:0全量,1增量 全量或者增量更新结束后都要将sys_treeview中的标志位变为9(已同步)
   * 当数据再次发生变化时,会将标志位变为1(有变化),增量时,只需要进行标志位为1的数据变化即可
   *
   * @param operationType
   */
  @Override
  public void TreetoOrg(String operationType) {
    // 下面解决难点,如何将level与systreeview进行转化
    // 根节点的level为1,root结点的level为2,root结点以下的结点为3,以此类推....
    // 方案一:从root结点入手,先进行root的整合,然后root的下级,依次类推
    if ("0".equals(operationType)) {
      // 海康有默认结点root000000,所有的root结点的父节点都是root000000
      SysTreeviewSearchVo sysTreeviewSearchVo = new SysTreeviewSearchVo();
      // 先进行root结点的筛选
      sysTreeviewSearchVo.setTvParentId("root");
      // 从原表中根据条件查,全量的时候进行deleted='0'的判断,只需要将有效的树关系转组织
      List<SysTreeview> rootList = sysTreeviewMP.queryAllByTvParentId(sysTreeviewSearchVo);

      HashMap<Org, List<SysTreeview>> rootChildMap = new HashMap<>();
      for (SysTreeview sysTreeview : rootList) {
        Org org = new Org();
        // 该代码是核心,将本地的树关系转为组织关系
        // 1.设置组织id
        org.setOrgId(sysTreeview.getId());
        // 2.设置父组织id
        org.setParentOrgId("root000000");
        // 3..设置组织层级
        org.setOrgLevel(1);
        // 4.设置组织名称
        org.setOrgName(sysTreeview.getItemName());
        // 5.设置操作类型
        org.setOperation(2);
        // 6.设置状态,0正常,-1删除
        org.setStatus("0".equals(sysTreeview.getDeleted()) ? 0 : -1);
        // 7.设置更新时间
        org.setUpdateTime(sysTreeview.getUpdateTime());
        // 8.保存到org表中,同时设置原表中的sync_flag=9(已同步)
        orgMP.save(org);
        sysTreeview.setSyncFlag("9");
        sysTreeviewMP.update(sysTreeview);
        // 查询子节点
        sysTreeviewSearchVo.setTvParentId(sysTreeview.getId());
        // 此处查子节点的时候也要进行deleted='0'的判断
        List childlist = sysTreeviewMP.queryAllByTvParentId(sysTreeviewSearchVo);
        // 将子节点加入到childMap中
        if (childlist != null && childlist.size() != 0) {
          rootChildMap.put(org, childlist);
        }
      }
      // 进行root孩子之间的操作
      while (rootChildMap != null && rootChildMap.size() > 0) {
        rootChildMap = ChildTreetoOrg(rootChildMap, "0");
      }
    } else {
      // 此处代码为增量更新
      // 增量更新只需要将原表中syn_flag=1的字段查出来,再进行增删改
      // 注意进行增量更新的时候需要将deleted='0'的字段省略掉,因为在源数据表中,一开始可能deleted='0',后来不为0
      SysTreeviewSearchVo sysTreeviewSearchVo = new SysTreeviewSearchVo();
      sysTreeviewSearchVo.setSyncFlag("1");
      List<SysTreeview> updateLists = sysTreeviewMP.query(sysTreeviewSearchVo);
      // 将org表已有父节点或者已有的数据进行更新或新增操作
      for (SysTreeview sysTreeview : updateLists) {
        // 查看在org表中是否存在该数据
        Org org = orgMP.get(sysTreeview.getId());
        // 如果存在,则进行更新
        if (org != null) {
          // 修改,注意有修改组织一说
          orgMP.update(
              new Org(
                  sysTreeview.getId(),
                  sysTreeview.getItemName(),
                  "root".equals(sysTreeview.getTvParentid()) ? "root000000" : sysTreeview.getTvParentid(),
                  "0".equals(sysTreeview.getDeleted()) ? 0 : -1,
                  sysTreeview.getUpdateTime(),
                  orgMP.get(sysTreeview.getTvParentid()).getOrgLevel() + 1,
                  1));
          sysTreeview.setSyncFlag("9");
          sysTreeviewMP.update(sysTreeview);
        } else if (orgMP.get(sysTreeview.getTvParentid()) != null) {
          // 该节点不存在org表,但是父节点在org表中存在,直接新增即可
          orgMP.save(
              new Org(
                  sysTreeview.getId(),
                  sysTreeview.getItemName(),
                  sysTreeview.getTvParentid(),
                  "0".equals(sysTreeview.getDeleted()) ? 0 : -1,
                  sysTreeview.getUpdateTime(),
                  orgMP.get(sysTreeview.getTvParentid()).getOrgLevel() + 1,
                  2));
          sysTreeview.setSyncFlag("9");
          sysTreeviewMP.update(sysTreeview);
        } else {
          // 剩下的就是父节点以及其本身都不在org表的数据,按照正常逻辑,至少有一个root结点
          HashMap<Org, List<SysTreeview>> ChildMap = new HashMap<>();
          if ("root".equals(sysTreeview.getTvParentid())) {
            Org orgroot =
                new Org(
                    sysTreeview.getId(),
                    sysTreeview.getItemName(),
                    "root000000",
                    "0".equals(sysTreeview.getDeleted()) ? 0 : -1,
                    sysTreeview.getUpdateTime(),
                    1,
                    2);
            orgMP.save(orgroot);
            SysTreeviewSearchVo sysTreeviewSearchVo1 = new SysTreeviewSearchVo();
            sysTreeviewSearchVo1.setTvParentId(sysTreeview.getId());
            List<SysTreeview> childquery = sysTreeviewMP.query(sysTreeviewSearchVo1);
            // 将子节点加入到childMap中
            if (childquery != null && childquery.size() != 0) {
              ChildMap.put(org, childquery);
            }
          }
          sysTreeview.setSyncFlag("9");
          sysTreeviewMP.update(sysTreeview);
          // 进行root孩子之间的操作
          while (ChildMap != null && ChildMap.size() > 0) {
            ChildMap = ChildTreetoOrg(ChildMap, "1");
          }
        }
      }
    }
  }

  @Override
  public HashMap ChildTreetoOrg(HashMap map, String operationType) {
    SysTreeviewSearchVo sysTreeviewSearchVo = new SysTreeviewSearchVo();
    HashMap childMap = new HashMap();
    Iterator<Map.Entry<Org, List<SysTreeview>>> iterator = map.entrySet().iterator();
    while (iterator.hasNext()) {
      Map.Entry<Org, List<SysTreeview>> entry = iterator.next();
      for (SysTreeview sysTreeview : entry.getValue()) {
        Org org = new Org();
        // 1.设置原id->组织id
        org.setOrgId(sysTreeview.getId());
        // 2.设置父组织id,需修改
        org.setParentOrgId(entry.getKey().getOrgId());
        // 3..设置组织层级,需修改
        org.setOrgLevel(entry.getKey().getOrgLevel() + 1);
        // 4.设置组织名称
        org.setOrgName(sysTreeview.getItemName());
        // 5.设置操作类型
        org.setOperation(2);
        // 6.设置状态,0正常,-1删除
        org.setStatus("0".equals(sysTreeview.getDeleted()) ? 0 : -1);
        // 7.设置更新时间
        org.setUpdateTime(sysTreeview.getUpdateTime());
        orgMP.save(org);
        sysTreeview.setSyncFlag("9");
        sysTreeviewMP.update(sysTreeview);
        sysTreeviewSearchVo.setTvParentId(org.getOrgId());
        List childlist;
        if ("0".equals(operationType)) {
          // 进行deleted='0'的判断
          childlist = sysTreeviewMP.queryAllByTvParentId(sysTreeviewSearchVo);

        } else {
          // 不进行deleted='0'的判断
          childlist = sysTreeviewMP.query(sysTreeviewSearchVo);
        }
        // 将子节点加入到childMap中
        if (childlist != null && childlist.size() != 0) {
          childMap.put(org, childlist);
        }
      }
    }
    return childMap;
  }

  @Override
  public Map<Object, Object> queryAllCount() {
    return orgMP.queryAllCount();
  }
}
